package com.jiaozi.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.func.LambdaUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.jiaozi.base.enums.sys.StateEnum;
import com.jiaozi.base.utils.bean.R;
import com.jiaozi.system.entity.SysMenu;
import com.jiaozi.system.entity.SysRoleOrMenu;
import com.jiaozi.system.mapper.SysRoleMapper;
import com.jiaozi.system.entity.SysRole;
import com.jiaozi.system.pojo.param.sys.role.RolePageParam;
import com.jiaozi.system.pojo.param.sys.role.RoleSaveUpdateParam;
import com.jiaozi.system.pojo.vo.sys.role.RoleInfoVO;
import com.jiaozi.system.pojo.vo.sys.role.RoleListVO;
import com.jiaozi.system.pojo.vo.sys.role.RolePageVO;
import com.jiaozi.system.service.SysMenuService;
import com.jiaozi.system.service.SysRoleOrMenuService;
import com.jiaozi.system.service.SysRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

/**
 * 系统-角色(SysRole)表服务实现类
 *
 * @author jiaozi
 * @since 2024-08-15 14:02:36
 */
@Service("sysRoleService")
public class SysRoleServiceImpl extends MPJBaseServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {

    @Autowired
    private SysRoleOrMenuService sysRoleOrMenuService;
    @Autowired
    private SysMenuService sysMenuService;
    @Override
    public R<IPage<RolePageVO>> rolePage(Long pageNum, Long pageSize, RolePageParam param) {
        Page page = new Page(pageNum, pageSize);
        MPJLambdaWrapper<SysRole> mpjLambdaWrapper=new MPJLambdaWrapper<>();
        mpjLambdaWrapper.selectAs(SysRole::getId,RolePageVO::getId);
        mpjLambdaWrapper.selectAs(SysRole::getRoleName,RolePageVO::getRoleName);
        mpjLambdaWrapper.selectAs(SysRole::getRoleSort,RolePageVO::getRoleSort);
        mpjLambdaWrapper.selectAs(SysRole::getRoleState,RolePageVO::getRoleState);
        mpjLambdaWrapper.selectAs(SysRole::getRoleRemarks,RolePageVO::getRoleRemarks);
        mpjLambdaWrapper.selectAs(SysRole::getCreatedTime,RolePageVO::getCreatedTime);
        mpjLambdaWrapper.like(StrUtil.isNotBlank(param.getRoleName()),SysRole::getRoleName,param.getRoleName());
        mpjLambdaWrapper.eq(param.getRoleState()!=null,SysRole::getRoleState,param.getRoleState());
//        String ss=SFunction<SysRole::getRoleSort;
//        BeanUtil.getFieldName(SysRole::getRoleSort)

        //用户自定义排序
        if(param.getZjSortOrder()!=null){
            mpjLambdaWrapper.orderBy(LambdaUtil.getFieldName(SysRole::getRoleSort).equals(param.getZjOrderProp()),param.getZjSortOrder().isAsc(), SysRole::getRoleSort);
            mpjLambdaWrapper.orderBy(LambdaUtil.getFieldName(SysRole::getCreatedTime).equals(param.getZjOrderProp()),param.getZjSortOrder().isAsc(), SysRole::getCreatedTime);
        }else{
            //默认排序
            mpjLambdaWrapper.orderBy(param.getZjSortOrder()==null,true,SysRole::getRoleSort,SysRole::getCreatedTime);
        }



        return R.ok(this.selectJoinListPage(page, RolePageVO.class,mpjLambdaWrapper));
    }

    @Override
    public R<List<RoleListVO>> roleList(RolePageParam param) {

        MPJLambdaWrapper<SysRole> mpjLambdaWrapper=new MPJLambdaWrapper<>();
        mpjLambdaWrapper.selectAs(SysRole::getId,RoleListVO::getId);
        mpjLambdaWrapper.selectAs(SysRole::getRoleName,RoleListVO::getRoleName);
        mpjLambdaWrapper.like(StrUtil.isNotBlank(param.getRoleName()),SysRole::getRoleName,param.getRoleName());
        mpjLambdaWrapper.eq(param.getRoleState()!=null,SysRole::getRoleState,param.getRoleState());

        return R.ok(this.selectJoinList(RoleListVO.class,mpjLambdaWrapper));
    }

    @Override
    public R<RoleInfoVO> roleInfo(String roleId) {
        Function<Object, String> f = (o -> o.toString());
        RoleInfoVO roleInfoVO=BeanUtil.copyProperties(this.getById(roleId),RoleInfoVO.class);
        if(roleInfoVO!=null){
            LambdaQueryWrapper<SysRoleOrMenu> sysRoleOrMenuLambdaQueryWrapper=new LambdaQueryWrapper<>();
            sysRoleOrMenuLambdaQueryWrapper.select(SysRoleOrMenu::getMenuId);
            sysRoleOrMenuLambdaQueryWrapper.eq(SysRoleOrMenu::getRoleId,roleId);
            roleInfoVO.setMenuIds(sysRoleOrMenuService.listObjs(sysRoleOrMenuLambdaQueryWrapper, f));
        }
        if(CollUtil.isNotEmpty(roleInfoVO.getMenuIds())){
        LambdaQueryWrapper<SysMenu> sysMenuLambdaQueryWrapper=new LambdaQueryWrapper<>();
        sysMenuLambdaQueryWrapper.notIn(SysMenu::getId,roleInfoVO.getMenuIds());
        List<String> list=sysMenuService.listObjs(sysMenuLambdaQueryWrapper,f);

            roleInfoVO.setMenuIsNullIds(list);
        }

        return R.ok(roleInfoVO);
    }

    @Override
    public R roleSave(RoleSaveUpdateParam roleSaveUpdateParam) {
        SysRole sysRole= BeanUtil.copyProperties(roleSaveUpdateParam,SysRole.class);
        this.save(sysRole);
        if(CollUtil.isNotEmpty(roleSaveUpdateParam.getMenuIds())){
            saveMenu(sysRole.getId(), roleSaveUpdateParam.getMenuIds());
        }
        return R.ok();
    }

    @Override
    public R roleUpdate(String roleId, RoleSaveUpdateParam roleSaveUpdateParam) {
        LambdaUpdateWrapper<SysRole> lambdaUpdateWrapper=new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.set(SysRole::getRoleName,roleSaveUpdateParam.getRoleName());
        lambdaUpdateWrapper.set(SysRole::getRoleSort,roleSaveUpdateParam.getRoleSort());
        lambdaUpdateWrapper.set(SysRole::getRoleRemarks,roleSaveUpdateParam.getRoleRemarks());
        lambdaUpdateWrapper.eq(SysRole::getId,roleId);
        this.update(lambdaUpdateWrapper);


        LambdaQueryWrapper<SysRoleOrMenu> sysRoleOrMenuLambdaQueryWrapper=new LambdaQueryWrapper<>();
        sysRoleOrMenuLambdaQueryWrapper.eq(SysRoleOrMenu::getRoleId,roleId);
        sysRoleOrMenuService.remove(sysRoleOrMenuLambdaQueryWrapper);

        if(CollUtil.isNotEmpty(roleSaveUpdateParam.getMenuIds())){
            saveMenu(Long.valueOf(roleId), roleSaveUpdateParam.getMenuIds());
        }
        return R.ok();
    }

    @Override
    public R roleDelete(String roleId) {
        this.removeById(roleId);
        return R.ok();
    }

    @Override
    public R updateRoleState(String roleId) {
        SysRole sysRole=this.getById(roleId);
        LambdaUpdateWrapper<SysRole> sysRoleLambdaUpdateWrapper=new LambdaUpdateWrapper<>();
        if(sysRole.getRoleState()==StateEnum.NORMAL){
            sysRoleLambdaUpdateWrapper.set(SysRole::getRoleState,StateEnum.STOP);
        }else{
            sysRoleLambdaUpdateWrapper.set(SysRole::getRoleState,StateEnum.NORMAL);
        }
        sysRoleLambdaUpdateWrapper.eq(SysRole::getId,roleId);
        this.update(sysRoleLambdaUpdateWrapper);
        return R.ok();
    }

    /**
     * 添加菜单
     * @param roleId
     * @param menuIds
     */
    public void saveMenu(Long roleId, List<String> menuIds){
        List<SysRoleOrMenu> sysRoleOrMenus=new ArrayList<>();
        for (String menuId : menuIds) {
            sysRoleOrMenus.add(new SysRoleOrMenu(roleId,Long.valueOf(menuId)));
        }
        sysRoleOrMenuService.saveBatch(sysRoleOrMenus);
    }


}

